#include <Windows.h>
#include "Sprite3D.h"

class cell{
public:
	float x,y,z;
	cell(int a,int b,int c){
		x=a;
		y=b;
		z=c;
	}
	void draw(GLuint &ModelView,mat4 &matModelView,Sprite3D *spr){
		glUniformMatrix4fv(ModelView,1,GL_TRUE,
			spr->mv*matModelView*spr->Roxyz);
		spr->Draw();
	}
};
class snake{
private:
	enum{UP,DOWN,LEFT,RIGHT,NUM_KEY};
	MatrixStack MVStack;
	vector<cell> sna;
	cell *food;
	int Size;
	mat4 r;
	enum{TEX_GROUND,diamond,texture_sun,diamond_glass,kont_color,star,NUM_MODEL};
	Sprite3D *spr[NUM_MODEL];
public:
	~snake(){
		delete []spr;
		delete food;
	}
	snake(int Len,GLuint progam){
		sna.clear();
		Size=Len;
		for (int i=0;i<Len;i++)
		{
			sna.push_back(cell(0,0,i));
		}
		const char* fileName[NUM_MODEL]={
			"res/qwe",
			"res/diamond",
			"res/texture_sun",
			"res/kont_color",
			"res/tour",
			"res/star"
		};
		for (int i=0;i<NUM_MODEL;i++)
		{
			spr[i]=new Sprite3D(fileName[i],progam,r,vec3(0,0,0),0);
		}
		SetFood();
	}
	void SetFood(){
		bool flag=true;
		while (flag)
		{
			flag=false;
			int a=rand()%11-5,b=0,c=rand()%11-5;
			for(int i=0;i<sna.size();i++)
			{
				if (sna[i].x==a&&sna[i].y==b&&sna[i].z==c)
				{
					flag=true;
					break;
				}
			}
			if (flag==false)
			{
				food=new cell(a,b,c);
			}
			
		}
	}
	void ReStart(){
		int temp=sna.size();
		for (int i=0;i<temp;i++)
		{
			sna.pop_back();
		}
		for (int i=0;i<Size;i++)
		{
			sna.push_back(cell(0,0,i));
		}
		SetFood();
	}
	bool failure(){
		for (int i=1;i<sna.size();i++)
		{
			if (sna[0].x==sna[i].x&&sna[0].y==sna[i].y&&sna[0].z==sna[i].z)
			{
				return true;
			}
			if (sna[0].x>5||sna[0].x<-5
				||sna[0].y>5||sna[0].y<-5
				||sna[0].z>5||sna[0].z<-5)
			{
				return true;
			}
		}
		return false;
	}
	void draw(GLuint &ModelView,mat4 &matModelView,int th,int ModelNum){
		for(int i=0;i<sna.size();i++)
		{
			MVStack.push(matModelView);
			matModelView*=Translate(sna[i].x,sna[i].y,sna[i].z);
			matModelView*=Rotate(th*3,1,1,1);
			sna[i].draw(ModelView,matModelView,spr[ModelNum]);
			matModelView=MVStack.pop();
		}
		MVStack.push(matModelView);
		matModelView*=Translate(food->x,food->y,food->z);
		matModelView*=RotateY(-th*6);
		food->draw(ModelView,matModelView,spr[ModelNum]);
		matModelView=MVStack.pop();
	}
	void update(int dir){
		if (sna[0].x==food->x&&sna[0].y==food->y&&sna[0].z==food->z)
		{
			sna.push_back(*(new cell(0,0,0)));
			delete food;
			SetFood();
		}
		for (int i=sna.size()-1;i>0;i--)
		{
			sna[i].x=sna[i-1].x;
			sna[i].y=sna[i-1].y;
			sna[i].z=sna[i-1].z;
		}
		switch (dir)
		{
		case UP:
			sna[0].z-=1;
			break;
		case DOWN:
			sna[0].z+=1;
			break;
		case LEFT:
			sna[0].x-=1;
			break;
		case RIGHT:
			sna[0].x+=1;
			break;
		}
		
	}
	bool win(){
		if (sna.size()==11*11)
			return true;
		else
			return false;
	}
};